#pragma once

#include "Channel.h"
#include "EventLoop.h"
#include "Socket.h"
#include "noncopyable.h"
#include "InetAddress.h"
#include "Callbacks.h"
#include "Buffer.h"
#include "Timestamp.h"

#include <memory>
#include <string>
#include <atomic>
#include <functional>


//std::enable_shared_from_this<TcpConnection>：这是 C++11 中的一个特性，用于帮助在基于共享指针的情况下创建对象的 shared_ptr。
//它允许一个对象能够安全地获取指向自身的 shared_ptr，即在对象自身内部创建一个 shared_ptr，用于管理该对象的生命周期。
/**
 * TcpServer=>Acceptor=>有一个新用户连接，通过accept函数拿到connfd，
 * 然后打包TcpConnection并且设置回调,将回调设置给Channel,Channel将自己注册到Poller,Poller监听到事件之后Channel会执行相应的回调操作
 * 用于描述已建立连接的客户端和服务器之间的联系
*/
class TcpConnection : noncopyable,public std::enable_shared_from_this<TcpConnection>
{
public:
    TcpConnection(EventLoop* loop,
                const std::string& name,
                int sockfd,
                const InetAddress& localAddr,
                const InetAddress& peerAddr);
    ~TcpConnection();

    EventLoop* getLoop() const { return loop_; }
    const std::string& name() const { return name_; }
    const InetAddress& localAddress() const { return localAddr_; }
    const InetAddress& peerAddress() const { return peerAddr_; }

    bool connected() const { return state_ == kConnected; }

    //发送数据
    void send(const std::string &buf);
    //关闭连接
    void shutdown();

    void setConnecionCallback(const ConnectionCallback& cb)
    { connectionCallback_ = cb; }

    void setMessageCallback(const MessageCallback& cb)
    { messageCallback_ = cb; }

    void setWriteCompleteCallback(const WriteCompleteCallback& cb)
    { writeCompleteCallback_ = cb; }

    void setHighWaterMarkCallback(const HighWaterMarkCallback& cb ,size_t highWaterMark)
    { highWaterMarkCallback_ = cb; highWaterMark_ = highWaterMark; }

    void setCloseCallback(const CloseCallback& cb)
    { closeCallback_ = cb; }

    //连接建立
    void connectEstablished();
    //连接销毁
    void connectDestroyed();

private:
    enum StateE {kDisconnected,kConnecting,kConnected,kDisconnecting};

    void setState(StateE state){ state_ = state; }

    void handleRead(Timestamp receiveTime);
    void handleWrite();
    void handleClose();
    void handleError();

    void sendInLoop(const void* data,size_t len);

    void shutdownInLoop();

    EventLoop* loop_; //这里绝对不是baseLoop,因为TcpConnection都是在subLoop里面管理的
    const std::string name_;
    std::atomic_int state_;
    bool reading_;

    //这里和Acceptor类似   Acceptor(里面是listenfd) 在mainloop里面, TcPConnection(里面是connfd)在subloop里面
    std::unique_ptr<Socket> socket_;
    std::unique_ptr<Channel> channel_;

    const InetAddress localAddr_; //当前主机的IP地址和端口号
    const InetAddress peerAddr_; //对端的IP地址和端口号

    ConnectionCallback connectionCallback_; //有新连接时的回调
    MessageCallback messageCallback_; //有读写消息时的回调
    WriteCompleteCallback writeCompleteCallback_; //消息发生完成以后的回调
    HighWaterMarkCallback highWaterMarkCallback_;
    CloseCallback closeCallback_;

    size_t highWaterMark_; //水位标志

    Buffer inputBuffer_;  //接收数据的缓冲区
    Buffer outputBuffer_; //发送数据的缓冲区
}; 